TO DO:
Need to be able to scatter plot measured values of Psi on top of the current Psi plot.
Alpha and rho LaTeX not working in plots.
Legend needs to be move in the Psi plot.
Consider also applying the scatter of the data and curve fit style of plotting for the parameters
Plots in general need to look better
LaTeX in all of the equations
In [1]:
import numpy as np
from scipy.integrate import quad, dblquad
%matplotlib inline
import matplotlib.pyplot as plt
This notebook calculates and plots the theoretical tilt angles. It will also plot the alpha and p0 factors vs temperature that are given in the cell below this.
In [2]:
thetamin = 25.6*np.pi/180
thetamax = 33.7*np.pi/180
t = 1*10**-6 #Cell Thickness
In [3]:
tempsC = np.array([26, 27, 29, 31, 33, 35, 37])
voltages = np.array([2,3,6,7,9,11,12.5,14,16,18,20,22,23.5,26,27.5,29,31,32.5,34,36])
alpha_micro = np.array([.2575,.2475,.2275,.209,.189,.176,.15])
p0Debye = np.array([650,475,300,225,160,125,100]) #Temperature Increases to the right
In [4]:
#This Block just converts units
fields = np.array([entry/t for entry in voltages])
debye = 3.33564e-30
p0_array = np.array([entry*debye for entry in p0Debye]) #debye units to SI units
k = 1.3806488e-23
p0k_array = np.array([entry/k for entry in p0_array]) #p0k is used because it helps with the integration
KC = 273.15
tempsK = np.array([entry+KC for entry in tempsC]) #Celsius to Kelvin
alpha_array = np.array([entry*1e-6 for entry in alpha_micro])
In [7]:
def Boltz(theta,phi,T,p0k,alpha,E):
"""Compute the integrand for the Boltzmann factor.
Returns
-------
A function of theta,phi,T,p0k,alpha,E to be used within dblquad
"""
return np.exp((1/T)*p0k*E*np.sin(theta)*np.cos(phi)*(1+alpha*E*np.cos(phi)))*np.sin(theta)
In [8]:
def Z_func(T,p0k,alpha,E,thetamin,thetamax):
"""Compute the Boltzmann factor by using dblquad to double integrate for a set of conditions.
Returns
-------
Float :
The Boltzmann factor, Z, at theta,phi,T,p0k,alpha,E
"""
Z, Z_error = dblquad(Boltz, 0, 2*np.pi,lambda theta: thetamin, lambda theta: thetamax,args=(T,p0k,alpha,E))
return Z
In [9]:
def numerator(theta,phi,T,p0k,alpha,E):
boltz = Boltz(theta,phi,T,p0k,alpha,E)
return np.sin(2*theta)*np.cos(phi)*boltz
In [10]:
def denominator(theta,phi,T,p0k,alpha,E):
boltz = Boltz(theta,phi,T,p0k,alpha,E)
return ((np.cos(theta)**2) - ((np.sin(theta)**2) * (np.cos(phi)**2)))*boltz
In [11]:
def compute_psi(T,p0k,alpha,E,thetamin,thetamax):
"""Computes the tilt angle(psi) by use of our tan(2psi) equation
Returns
-------
Float:
The statistical tilt angle with conditions T,p0k,alpha,E
"""
avg_numerator, avg_numerator_error = dblquad(numerator, 0, 2*np.pi, lambda theta: thetamin, lambda theta: thetamax,args=(T,p0k,alpha,E))
avg_denominator, avg_denominator_error = dblquad(denominator, 0, 2*np.pi, lambda theta: thetamin, lambda theta: thetamax,args=(T,p0k,alpha,E))
psi = np.arctan(avg_numerator / (avg_denominator)) * (180 /(2*np.pi)) #Converting to degrees from radians and divide by two
return psi
In [12]:
def psi_all(tempsK,fields,alpha_array,p0k_array,thetamin,thetamax):
"""Constructs an array where each entry in the array is an array of computed Psis at a Temperature.
Parameters/Conditions
----------
theta:
Tilt Angle
phi:
Azimuthal Angle
T:
Temperature
p0k:
Dipole moment p0/k. Where k is Boltzmann's constant
alpha:
Tilt Susceptibility
E:
Applied Electric Field
Returns
-------
Array: M Dimensional Entry with N entries. Where N is the number of Applied Electric Fields.
M is the number of Temperatures.
"""
def psi_array(T,p0k,alpha,fields,thetamin,thetamax):
"""Computes thes tilt angles(psi) from tan(2psi) for every electric field applied at a constant Temperature
Returns
-------
Array: 1 Dimensional Entry with N entries. Where N is the number of Applied Electric Fields
"""
Psi_Array = np.array([compute_psi(T,p0k,alpha,E,thetamin,thetamax) for E in fields])
return Psi_Array
return np.array([psi_array(tempsK[i],p0k_array[i],alpha_array[i],fields,thetamin,thetamax) for i in range(len(tempsK))])
AllPsi_Array = psi_all(tempsK,fields,alpha_array,p0k_array,thetamin,thetamax)
In [14]:
def plot_psi(AllPsi,voltages,tempsK):
""" Sets up plotting visual settings and plots the computed Psi arrays at each temperature"""
plt.figure(figsize=(9,6));
for j in range(len(AllPsi)):
name = str(int(tempsK[j]-273.15)) + '$^{\circ}$C'
plt.plot(voltages,AllPsi[j],label = name );
plt.title('Tilt Angle vs Electric Field');
plt.xlabel('Applied Electric Field E/$\mu$m')
plt.ylabel('Tilt Angle $\psi$')
plt.xlim(0,voltages.max()+2)
plt.ylim(0,AllPsi_Array[0].max()+2)
plt.legend(loc=4)
In [15]:
plot_psi(AllPsi_Array,voltages,tempsK)
In [16]:
def plot_parameters(alpha_array,p0_array,tempsK):
""" Sets up plotting visual settings and plots parameters alpha and p0 vs temperature"""
tempsC = np.array([i-273 for i in tempsK])
p0_debye = np.array([i/3.33e-30 for i in p0_array])
alpha_um = np.array([i/1e-6 for i in alpha_array])
fig, (ax1,ax2) = plt.subplots(2,1,figsize=(6,8));
plt.sca(ax2);
plt.scatter(tempsC,p0_debye);
plt.title('Polarization Parameter vs Temperature');
plt.xlabel('Temperature $^{\circ}$C');
plt.ylabel('rho (debye)');
plt.sca(ax1);
plt.scatter(tempsC,alpha_um);
plt.title('Alpha Parameter vs Temperature');
plt.xlabel('Temperature $^{\circ}$C');
plt.ylabel('alpha ($\mu$m/V)');
plt.tight_layout();
In [17]:
plot_parameters(alpha_array,p0_array,tempsK)
In [ ]: